﻿using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 扇形布局控件
/// </summary>
public class SectorLayoutGroup : LayoutGroup
{
    public enum LayoutModeEnum
    {
        /// <summary>
        /// 平均分布
        /// </summary>
        Hypodispersion,
        /// <summary>
        /// 固定间隔分布
        /// </summary>
        FixSpace,
    }

    public enum FillTypeEnum
    {
        /// <summary>
        /// 从角度起始位置填充
        /// </summary>
        Start,
        /// <summary>
        /// 从中间位置扩散
        /// </summary>
        Center,
    }

    /// <summary>
    /// 是否为顺时针
    /// </summary>
    public bool isClockwise = false;
    public LayoutModeEnum layoutMode = LayoutModeEnum.Hypodispersion;
    public FillTypeEnum fillType = FillTypeEnum.Center;

    [Header("半径")]
    public float radius = 0;
    [Header("起始角度")]
    public float startAngle = 0;
    [Header("角度范围，平均模式起效")]
    [Range(0, 360)]
    public float rangeAngle = 0;
    [Header("固定间距，固定模式起效")]
    public float fixAngle = 0;

    protected override void OnEnable()
    {
        base.OnEnable();
        CalculateRadial();
    }
    public override void SetLayoutHorizontal()
    {
        CalculateRadial();
    }
    public override void SetLayoutVertical()
    {
        CalculateRadial();
    }
    public override void CalculateLayoutInputHorizontal()
    {
        base.CalculateLayoutInputHorizontal();
        CalculateRadial();
    }
    public override void CalculateLayoutInputVertical()
    {
        CalculateRadial();
    }

#if UNITY_EDITOR
    protected override void OnValidate()
    {
        base.OnValidate();
        CalculateRadial();
    }
#endif

    protected void CalculateRadial()
    {
        if (transform.childCount == 0) return;

        switch (layoutMode)
        {
            case LayoutModeEnum.Hypodispersion:
                Hypodispersion();
                break;
            case LayoutModeEnum.FixSpace:
                FixSpace();
                break;
        }
    }

    /// 平均分布
    private void Hypodispersion()
    {
        float startRad = 0;
        if (fillType == FillTypeEnum.Center && rectChildren.Count == 1)
        {
            startRad = (startAngle + rangeAngle) / 2;
        }
        else
        {
            startRad = startAngle;
        }

        startRad *= Mathf.Deg2Rad;
        var spaceCount = rectChildren.Count == 1 ? 1 : rectChildren.Count - 1;
        var perRad = (rangeAngle / spaceCount) * Mathf.Deg2Rad;
        perRad = isClockwise ? -perRad : perRad;
        SetLayout(startRad, perRad);
    }

    /// 固定间距
    private void FixSpace()
    {
        float startRad = 0;
        switch (fillType)
        {
            case FillTypeEnum.Start:
                startRad = startAngle;
                break;
            case FillTypeEnum.Center:
                var spaceCount = rectChildren.Count - 1;
                var offetSpace = spaceCount * fixAngle / 2;
                startRad = isClockwise ? startAngle + offetSpace : startAngle - offetSpace;
                break;
        }
        startRad *= Mathf.Deg2Rad;
        var perRad = fixAngle * Mathf.Deg2Rad;
        perRad = isClockwise ? -perRad : perRad;
        SetLayout(startRad, perRad);
    }

    private void SetLayout(float startRad, float perRad)
    {
        for (int i = 0; i < rectChildren.Count; i++)
        {
            var child = rectChildren[i];

            Vector3 vPos = child.localPosition;
            var rad = startRad + perRad * i;
            vPos.x = this.radius * Mathf.Cos(rad);
            vPos.y = this.radius * Mathf.Sin(rad);
            child.localPosition = vPos;
        }

    }
}
